package com.mi.rule.db.dao;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mi.rule.db.core.MiWrapper;
import com.mi.rule.db.entity.MiEntity;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * 强化 DAO
 *
 * @author 王永吉
 */
public interface MiDao {
    // 插入一条记录（选择字段，策略插入）
    <P extends MiEntity> long insert(P entity);

    // 插入（批量）
    <P extends MiEntity> long insertBatch(List<P> entityList);

    // 插入（批量）
    <P extends MiEntity> long insertBatch(List<P> entityList, int batchSize);

    // TableId 注解存在更新记录，否插入一条记录
    <P extends MiEntity> long insertOrUpdate(P entity);

    // 根据miWrapper尝试更新，否继续执行insertOrUpdate(P)方法
    <P extends MiEntity> long insertOrUpdate(P entity, MiWrapper<P> miWrapper);

    // 批量修改插入
    <P extends MiEntity> long insertOrUpdateBatch(List<P> entityList);

    // 批量修改插入
    <P extends MiEntity> long insertOrUpdateBatch(List<P> entityList, int batchSize);


    // 根据 entity 条件，删除记录
    <P extends MiEntity> long delete(MiWrapper<P> miWrapper);

    // 根据 ID 删除
    <P extends MiEntity> long deleteById(Class<P> pClass, Serializable id);

    // 根据 columnMap 条件，删除记录
    <P extends MiEntity, MP extends Map<?, ?>> long deleteByMap(Class<P> pClass, MP columnMap);

    // 删除（根据ID 批量删除）
    <P extends MiEntity> long deleteByIds(Class<P> pClass, List<? extends Serializable> idList);


    // 根据 UpdateWrapper 条件，更新记录 需要设置sqlset
    <P extends MiEntity> long update(MiWrapper<P> miWrapper);

    // 根据 whereEntity 条件，更新记录
    <P extends MiEntity> long update(P entity, MiWrapper<P> miWrapper);

    // 根据 ID 选择修改
    <P extends MiEntity> long updateById(P entity);

    // 根据ID 批量更新
    <P extends MiEntity> long updateBatchById(List<P> entityList);

    // 根据ID 批量更新
    <P extends MiEntity> long updateBatchById(List<P> entityList, int batchSize);


    // 根据 ID 查询
    <P extends MiEntity> P selectById(Class<P> pClass, Serializable id);

    // 根据 Wrapper，查询一条记录。结果集，如果是多个会抛出异常，随机取一条加上限制条件 wrapper.last("LIMIT 1")
    <P extends MiEntity> P selectOne(MiWrapper<P> miWrapper);

    // 根据 Wrapper，查询一条记录
    <P extends MiEntity> Map<String, Object> selectMap(MiWrapper<P> miWrapper);

    // 查询所有
    <P extends MiEntity> List<P> list(Class<P> pClass);

    // 查询列表
    <P extends MiEntity> List<P> list(MiWrapper<P> miWrapper);

    // 查询（根据ID 批量查询）
    <P extends MiEntity> List<P> listByIds(Class<P> pClass, List<? extends Serializable> idList);

    // 查询（根据 columnMap 条件）
    <P extends MiEntity> List<P> listByMap(Class<P> pClass, Map<String, Object> columnMap);

    // 查询所有列表
    <P extends MiEntity> List<Map<String, Object>> listMaps(Class<P> pClass);

    // 查询列表
    <P extends MiEntity> List<Map<String, Object>> listMaps(MiWrapper<P> miWrapper);

    // 查询全部记录
    <P extends MiEntity> List<Object> listObjs(Class<P> pClass);

    // 根据 Wrapper 条件，查询全部记录
    <P extends MiEntity> List<Object> listObjs(MiWrapper<P> miWrapper);

    // 查询总记录数
    <P extends MiEntity> long count(Class<P> pClass);

    // 根据 Wrapper 条件，查询总记录数
    <P extends MiEntity> long count(MiWrapper<P> miWrapper);

    // 无条件翻页查询
    <P extends MiEntity> IPage<P> page(IPage<P> page, Class<P> pClass);

    // 翻页查询
    <P extends MiEntity> IPage<P> page(IPage<P> page, MiWrapper<P> miWrapper);

    // 无条件翻页查询
    <P extends MiEntity> IPage<Map<String, Object>> pageMaps(IPage page, Class<P> pClass);

    // 翻页查询
    <P extends MiEntity> IPage<Map<String, Object>> pageMaps(IPage page, MiWrapper<P> miWrapper);


    /**
     * 非实体类操作
     * ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
     */
    long insert(String sqlString);

    long insert(String tableName, Map map);

    long delete(String sqlString);

    long deleteById(String tableName, Serializable id);

    long deleteByIds(String tableName, List<? extends Serializable> idList);

    long update(String sqlString);

    long updateById(String tableName, Map map, Serializable id);

    long updateByIds(String tableName, Map map, List<Serializable> ids);

    Map<String, Object> selectOne(String sqlString);

    List<Map<String, Object>> list(String sqlString);

    List<Object> listObjs(String sqlString);

    long count(String sqlString);

    IPage<Map<String, Object>> page(IPage<Map<String, Object>> page, String sqlString);

}
